package com.markchu.web.structure.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.markchu.common.data.PageSort;
import com.markchu.common.enums.StatusEnum;
import com.markchu.common.utils.CookieUtils;
import com.markchu.common.utils.ResultVoUtil;
import com.markchu.common.vo.MessageInfosVo;
import com.markchu.common.vo.ResultVo;
import com.markchu.component.actionLog.annotation.EntityParam;
import com.markchu.component.redis.utils.RedisHelper;
import com.markchu.modules.system.domain.*;
import com.markchu.modules.system.enums.FileTypeEnum;
import com.markchu.modules.system.service.*;
import com.markchu.modules.system.vo.SaysayVo;
import com.markchu.web.structure.vo.ChatsVo;
import com.markchu.web.structure.vo.UploadVo;
import com.markchu.web.structure.vo.UserInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping("/home/api")
public class HomeApiController extends BaseController{


    @Autowired
    private UserService userService;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private ActivityJoinUserService activityJoinUserService;

    @Autowired
    private ActivityUserPicService activityUserPicService;

    @Autowired
    private ChatsService chatsService;

    @Autowired
    private SaysayService saysayService;

    @RequestMapping("/getToken")
    @ResponseBody
    public void getToken(){
        System.out.println("getToken");
    }

    @PostMapping("/says")
    public ResultVo mymsgs(Model model, SaysayVo saysayVo,HttpServletRequest request, HttpServletResponse response) {
        System.out.println("---"+saysayVo);
        Saysay saysay = new Saysay();
        saysay.setTitle(saysayVo.getTitle());
        saysay.setContents(saysayVo.getContents());
        saysay.setFileIds(saysayVo.getFileIds());
        saysay.setCookieId(request.getRequestedSessionId());
        Saysay result = saysayService.save(saysay);
        return ResultVoUtil.success();
    }

    @PostMapping("/LoadSays")
    public ResultVo LoadSays(Saysay saysay){
        ResultVo resultVo = new ResultVo();
        ExampleMatcher matcher = ExampleMatcher.matching();
        saysay.setStatus(StatusEnum.OK.getCode());
        Example<Saysay> example = Example.of(saysay, matcher);
        Page<Saysay> saysayPage = saysayService.getPageList(example);
        resultVo.setData(saysayPage);
        return resultVo;
    }
    @PostMapping("/updateSays/{dataId}")
    public ResultVo updateSays(@PathVariable Long dataId){
        saysayService.updateSays(dataId);
        return ResultVoUtil.success();
    }


    @PostMapping("/chats/{fromUserId}/{toUserId}")
    public ResultVo mymsgs(Model model, @PathVariable Long fromUserId, @PathVariable Long toUserId,String msgs) {
        Chats chats = new Chats();
        chats.setFromUserId(fromUserId);
        chats.setToUserId(toUserId);
        chats.setFromAndTo(fromUserId+toUserId);
        chats.setMsgs(msgs);
        Chats newChats = chatsService.save(chats);

        ChatsVo chatsVo = BeanUtil.copyProperties(newChats, ChatsVo.class);

        List<Long> userIds = new ArrayList<>();
        userIds.add(fromUserId);
        Map<Long, UserInfoVo> userIdNickNameMap = getUserIdNickNameMap(userIds);
        chatsVo.setUserFromThum(userIdNickNameMap.get(fromUserId).getUserThum());
        return ResultVoUtil.success(chatsVo);
    }

    @PostMapping("/loadChats/{fromUserId}/{toUserId}")
    public ResultVo loadChats(Model model, @PathVariable Long fromUserId, @PathVariable Long toUserId,String lastTime) {
        ResultVo resultVo = new ResultVo();
        // 创建匹配器，进行动态查询匹配
        Chats chats = new Chats();
        chats.setFromAndTo(fromUserId+toUserId);
        chats.setStatus(StatusEnum.OK.getCode());
        if(StringUtils.isEmpty(lastTime)){
            chats.setCreateDate(DateUtils.addDays(new Date(),-360));
        }else{
            chats.setCreateDate(DateUtil.parseDateTime(lastTime));
        }


        List<Chats> dataList = chatsService.findPageList(chats);
        List<ChatsVo> resultList = BeanUtil.copyToList(dataList, ChatsVo.class);

        List<Long> userIds = new ArrayList<>();
        userIds.add(fromUserId);
        userIds.add(toUserId);
        Map<Long, UserInfoVo> userIdNickNameMap = getUserIdNickNameMap(userIds);

        for(ChatsVo chatsVo : resultList){
            UserInfoVo from = userIdNickNameMap.get(chatsVo.getFromUserId());
            chatsVo.setUserFromThum(from.getUserThum());

            UserInfoVo to = userIdNickNameMap.get(chatsVo.getToUserId());
            chatsVo.setUserToThum(to.getUserThum());
            chatsVo.setUserName(to.getNickName());

            String oType = "ask";
            if(!getUserIdBy().equals(chatsVo.getFromUserId())){
                oType = "reply";
            }
            chatsVo.setOType(oType);
            resultVo.setEndIng(DateUtil.formatDateTime(chatsVo.getCreateDate()));
        }
        if(Objects.equals(resultList,null) || (!Objects.equals(resultList,null) && resultList.size()==0)){
            resultVo.setEndIng(DateUtil.formatDateTime(new Date()));
        }
        resultVo.setData(resultList);
        resultVo.setCode(200);
        return resultVo;
    }

    @PostMapping("/loadUserInfo")
    @ResponseBody
    public ResultVo loadUserInfo(){
        User user = getUserInfo();
        if(Objects.equals(user,null)){
            return ResultVoUtil.error();
        }
        return ResultVoUtil.success();
    }

    @PostMapping("/ac/joinuser/{ajuId}")
    @ResponseBody
    public ResultVo joinClicks(@PathVariable Long ajuId){
        ActivityJoinUser activityJoinUser = activityJoinUserService.getById(ajuId);
        /**
         * 判断是否已经过了投票日期
         */
        Activity activity = activityService.getById(activityJoinUser.getAc_id());
        Date thisDate = DateUtil.parseDate(DateUtil.formatDate(new Date()));
        Date endDate = DateUtil.parseDate(DateUtil.formatDate(activity.getAc_end_time()));
        long days = DateUtil.between(thisDate,endDate,DateUnit.DAY,false);
        if(days<0){
            return ResultVoUtil.error("该活动已经截止。谢谢!其他活动马上开始,敬请期待...");
        }
        //活动Id + 人员Id + 日期
        String keyCode = activityJoinUser.getAc_id()+"-"+getUserIdBy()+"-"+DateUtil.formatDate(new Date());
        if(RedisHelper.exists(keyCode)){
            return ResultVoUtil.error("同一天同一个活动只能头一次票。谢谢!");
        }
        activityJoinUser.setClicks(activityJoinUser.getClicks()+1);
        activityJoinUserService.save(activityJoinUser);


        activity.setClicks(activity.getClicks()+1);
        activityService.save(activity);

        RedisHelper.set(keyCode,"1");
        RedisHelper.expire(keyCode,MessageInfosVo.ONE_DAY_SECONDS);
        return ResultVoUtil.success("投票成功。谢谢!");
    }

    @PostMapping("/activityViews/{acId}")
    @ResponseBody
    public ResultVo<List<List<Upload>>> activityViews(@PathVariable Long acId){
        ResultVo resultVo = new ResultVo();
        Activity activity = activityService.getById(acId);
        activity.setViews(activity.getViews()+1);
        activityService.save(activity);
        return resultVo;
    }

    @PostMapping("/activityJoin")
    @ResponseBody
    public ResultVo activityJoin(Long activityId,@RequestParam("fileId") Long[] fileId,
                                 HttpServletRequest request, HttpServletResponse response){

        Long userId = getUserIdBy();
        Activity activity = activityService.getById(activityId);
        if(Objects.equals(activity.getJoins(),activity.getMaxJoins())){
            return ResultVoUtil.error("该活动已经到达最大人数限制,不能再参加。谢谢!");
        }

        boolean checkhas = activityJoinUserService.getObjectBy(userId,activityId);
        if(!checkhas){
            return ResultVoUtil.error("已经参加,不能再次提交。谢谢!");
        }

        //------------------------跟新活动对应的人员--------------------------------
        ActivityJoinUser activityJoinUser = new ActivityJoinUser();
        activityJoinUser.setAc_id(activityId);
        activityJoinUser.setUser_id(userId);
        activityJoinUser.setClicks(0L);
        activityJoinUserService.save(activityJoinUser);
        //-------------------------跟新活动对应的图片-------------------------------
        activityUserPicService.batchSave(activityJoinUser.getId(),activityId,userId,fileId);
        //-----------------------更新活动参加人数---------------------------------
        activityService.updateNumber("joins",activityId);
        return ResultVoUtil.success("成功加入活动");
    }

    @PostMapping("/login")
    public ResultVo login(String username, String vcode, String password,
                          HttpServletRequest request, HttpServletResponse response) {
        ResultVo resultVo = new ResultVo();
        String mobile_key_code = "key_" + username + "_" + vcode;
        String mk_value = RedisHelper.get(mobile_key_code);
        if(!Objects.equals(mk_value,password)){
            resultVo.setMsg(MessageInfosVo.ERROR_MOBILE_MSGS);
            return resultVo;
        }

        User user = userService.getByName(username,1);
        if(Objects.equals(user,null)){
            user = new User();
            user.setPhone(username);
            user.setUsername(username);
            user.setNickname(username);
            user.setUserType(1);
            userService.save(user);
        }

        String keyCode = UUID.fastUUID().toString();
        CookieUtils.setCookie(null,response,MessageInfosVo.SESSION_CODE, keyCode);
        RedisHelper.set(keyCode,String.valueOf(user.getId()));
        return ResultVoUtil.success();
    }

    @PostMapping("/update")
    public ResultVo login(@EntityParam User user) {
        if (user.getId() == null) {
            return ResultVoUtil.error();
        }
        userService.updateUserById(user);
        return ResultVoUtil.success("修改成功");
    }

    @PostMapping("/loadUpload")
    @ResponseBody
    public ResultVo<List<List<Upload>>> AjaxLoadUpload(Upload upload){
        ResultVo resultVo = new ResultVo();
        // 创建匹配器，进行动态查询匹配
        ExampleMatcher matcher = ExampleMatcher.matching();
        upload.setFileType(FileTypeEnum.WEB.getCode());
        upload.setStatus(Long.valueOf(StatusEnum.OK.getCode()));
        Example<Upload> example = Example.of(upload, matcher);

        Page<Upload> uploads = uploadService.getPageList(example);

        if(!Objects.equals(uploads,null)){
            List<List<UploadVo>> results = averageAssign(uploads.getContent(),2);
            resultVo.setData(results);
        }
        if(uploads.getContent().size()<20){
            resultVo.setMsg("last");
        }
        return resultVo;
    }

    @PostMapping("/fileClicks/{fileId}")
    @ResponseBody
    public ResultVo fileClicks(@PathVariable Long fileId){
        ResultVo resultVo = new ResultVo();
        Upload upload = uploadService.findById(fileId);
        Long clicks = upload.getClicks()+1;
        upload.setClicks(clicks);
        uploadService.save(upload);
        resultVo.setData(clicks);
        return resultVo;
    }


    public <T> List<List<UploadVo>> averageAssign(List<Upload> list, int n){
        List<UploadVo> dataList = getUserInfoList(list);
        List<List<UploadVo>> result=new ArrayList<List<UploadVo>>();
        int remaider=dataList.size()%n;  //(先计算出余数)
        int number=dataList.size()/n;  //然后是商
        int offset=0;//偏移量
        for(int i=0;i<n;i++){
            List<UploadVo> value = null;
            if(remaider>0){
                value=dataList.subList(i*number+offset, (i+1)*number+offset+1);
                remaider--;
                offset++;
            }else{
                value=dataList.subList(i*number+offset, (i+1)*number+offset);
            }
            result.add(value);
        }
        return result;
    }

    public <T> List<UploadVo> getUserInfoList(List<Upload> dataList) {
        List<UploadVo> resultList = BeanUtil.copyToList(dataList, UploadVo.class);
        List<Long> userIds = new ArrayList<>();
        for(UploadVo uploadVo : resultList){
            userIds.add(uploadVo.getUserId());
        }
        Map<Long, UserInfoVo> userIdNickNameMap = getUserIdNickNameMap(userIds);
        for(UploadVo uploadVo : resultList){
            UserInfoVo userInfoVo = userIdNickNameMap.get(uploadVo.getUserId());
            String nickName = userInfoVo.getNickName();
            if(StringUtils.isNotEmpty(nickName) && nickName.length()>5){
                nickName = nickName.substring(0,5);
            }
            uploadVo.setUserNickName(nickName);
            uploadVo.setUserThum(userInfoVo.getUserThum());
        }
        return resultList;
    }
}
